/**
 * Copyright (C) 2008 Christopher Allen Ogden
 *
 *     This file is part of Odysi.
 *
 *  Odysi is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Odysi is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Odysi.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once
#include <lua.hpp>
#include <iostream>
#include "postService.h"
#include "serverLua.h"
#include "luaAux.h"

/**
 * Stores a client connection.
 */
class Client
{
    public:
        /**
         * Constructor.
         *
         * @param sock  The socket.
         */
        Client(int sock, lua_State *L):_post(sock),_L(L),_id(0)
        {
        }

        /**
         * Process connection.
         */
        void process(void)
        {
            _post.process();
            Packet packet = _post.recv();
            // Only process one packet so that it is fair
            // to all the clients.
            if (packet.getLength()) {
                switch (static_cast<int>(reinterpret_cast<const char *>(packet.getData())[0])) {
                    case PH_LOGIN:
                        {
                        const genPacket::LoginPacket *lp(reinterpret_cast<const genPacket::LoginPacket *>(packet.getData()));
                        call_gotLoginPacket(_L, _post.getSocket(), lp->name, lp->pass);
                        }
                        break;
                    case PH_MOVE_REQUEST:
                        {
                        const genPacket::MoveRequestPacket *mrp(reinterpret_cast<const genPacket::MoveRequestPacket *>(packet.getData()));
                        call_gotMoveRequestPacket(_L, _post.getSocket(), mrp->dir);
                        }
                        break;
                    case PH_LUA_REMOTE_CALL:
                        Lua::processRemoteCall(_L, packet, _post.getSocket());
                        break;
                }
            }
        }

        /**
         * Get the socket.
         *
         * @return  The socket.
         */
        int getSocket(void) const
        {
            return _post.getSocket();
        }

        /**
         * Send a packet.
         *
         * @param p The packet.
         */
        void send(const Packet &p)
        {
            _post.send(p);
        }

        /**
         * Set character ID.
         *
         * @param id    Character ID.
         */
        inline void setCharID(unsigned int id) { _id = id; }
        inline unsigned int getCharID(void) const { return _id; }
    private:
        PostService _post;
        lua_State *_L;
        unsigned int _id; // Character ID
};
